package com.pet_service.config;

import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.pet_service.entity.Permission;
import com.pet_service.entity.Role;
import com.pet_service.entity.User;
import com.pet_service.mapper.PermissionMapper;
import com.pet_service.mapper.RoleMapper;
import com.pet_service.mapper.UserMapper;
import com.pet_service.result.Result;
import com.pet_service.service.PermissionService;
import com.pet_service.util.JwtUtil;
import jakarta.annotation.Resource;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.util.*;

//登录成功处理器
@Component // 将类标记为 Spring 管理的 Bean,交给IOC容器管理
@Slf4j // 日志
public class LoginSuccessHandler implements AuthenticationSuccessHandler {
    @Resource
    private UserMapper userMapper;
    @Resource
    private RoleMapper roleMapper;
    @Resource
    private PermissionMapper permissionMapper;
    @Resource
    private PermissionService permissionService;

    //一旦登录成功，就会调用这个方法
    @Override
    public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response,
                                        Authentication authentication) throws IOException, ServletException {
        //生成token值，将值传递给前端vue项目
        //<1> 设置响应数据格式
        response.setContentType("application/json;charset=utf-8");
        //<2>获取已经认证成功的用户
        UserDetails userDetails = (UserDetails) authentication.getPrincipal();
        String username = userDetails.getUsername();
        log.info("认证成功的用户名:{}",username);
        // 根据用户更新用户最后登录时间 update sys_user set login_date=? where username=?
        UpdateWrapper<User> updateWrapper=new UpdateWrapper<>();
        updateWrapper.set("login_date",new Date());// 修改最后登录时间
        updateWrapper.eq("username",username);
        userMapper.update(updateWrapper);
        //<3>根据用户名创建token值
        Map<String, String> claims = new HashMap<>();
        claims.put("username", username);
        String token = JwtUtil.generateToken("mySecret","pet_service","userAuth",claims);
        //<4>根据用户名获取用户信息
        User user =userMapper.selectByUsername(username);
        //获取角色列表
        List<Role> roleList = roleMapper.selectRoleByUserId(user.getId());
        //将查询到的角色列表设置到用户对象中
        user.setRoleList(roleList);
        //获取权限列表
        List<Permission> permissionList = permissionMapper.selectPermissionByRoleId(roleList);
        //权限按照order_num的值进行排序
        permissionList.sort(Comparator.comparing(Permission::getOrder_num));
        //构建菜单目录
        List<Permission> menuList = permissionService.buildTreePermission(permissionList);
        HashMap<String,Object> map =new HashMap<>();
        map.put("jwtToken", token);
        map.put("menuList", menuList);
        map.put("user", user);
        log.info("菜单信息:{}", menuList);
        //<4> 封装传递给前端vue项目的对象
        Result<HashMap> r = Result.ok(200, "登录成功", map);
        //<5> 将对象转换成json格式字符串
        String jsonStr = JSONUtil.toJsonStr(r);
        //<6> 使用字符输出流传递数据
        response.getWriter().write(jsonStr);
    }
}
